package net.yambal.RTM.Method
{
	import flash.events.EventDispatcher;
	
	import net.yambal.RTM.Event.AuthEvent;
	import net.yambal.RTM.Event.RestErrorEvent;
	import net.yambal.RTM.Event.RestEvent;
	import net.yambal.RTM.Items.RTMTransaction;
	import net.yambal.RTM.Items.RTMUser;
	import net.yambal.RTM.RestWrapper.RestManager;
	import net.yambal.RTM.RestWrapper.RestParameters;
	import net.yambal.RTM.RestWrapper.RestService;
	
	[Event(name="frob", type="net.yambal.RTM.Event.AuthEvent")]
	[Event(name="token", type="net.yambal.RTM.Event.AuthEvent")]
	[Event(name="check_token", type="net.yambal.RTM.Event.AuthEvent")]
	public class Auth extends EventDispatcher
	{
		
		// ---------------------------------------------------------------------------------
		/**
		 * Frobを取得する
		 *  getTokenで101が出たときにもここに来る
		 **/
		public function getFrob(api_key:String, shared_secret:String):void{
			var RM:RestManager = new RestManager();
			
			var p:Object = new Object();
			p.api_key = api_key;
			
			RM.doMethod(RestService.METHOD_AUTH_GET_FROB, p, this.onGetFrob, this.onFaultGetFrob, false, shared_secret);
		}
		
		// エラー
		private function onFaultGetFrob(code:Number, massage:String, ro:Object):void{
			// エラー処理
		}
		
		// 成功
		private function onGetFrob(result_xml:XML, ro:Object, t:RTMTransaction):void{
			var frob:String = result_xml.descendants("frob");
			trace("onGetFrob:" + frob);
			this.dispatchEvent(new AuthEvent(AuthEvent.FROB, frob, this.getWebAuthURL(ro.parameta.api_key, ro.shared_secret, frob)));
		}
		
		// ---------------------------------------------------------------------------------
		/**
		 * Tokenを取得する
		 * Frobが無効の場合、自動的に取得ルーチンに入るので、実行の結果frobイベントが発生する可能性もある
		 **/
		public function getToken(api_key:String, shared_secret:String, frob:String):void{
			var RM:RestManager = new RestManager();
			
			var p:Object = new Object();
			p.api_key = api_key;
			p.frob = frob;
			
			RM.doMethod(RestService.METHOD_AUTH_GET_TOKEN, p, this.onGetToken, this.onFaultGetToken, false, shared_secret);
		}
		
		// エラー
		private function onFaultGetToken(code:Number, massage:String, ro:Object):void{
			if(code == 101){
				// WEB認証が必要
				//　Frobの取得からやり直す...getTokenをするとFrobは無効になる様子
				this.getFrob(ro.parameta.api_key, ro.shared_secret);
				return;
			}
			// エラー処理
		}
		
		private function onGetToken(result_xml:XML, ro:Object, t:RTMTransaction):void{
			var u:RTMUser = new RTMUser();
			u.id = result_xml.auth.user.@id;
			u.user_name = result_xml.auth.user.@username;
			u.full_name = result_xml.auth.user.@fullname;
			
			this.dispatchEvent(new AuthEvent(AuthEvent.TOKEN, null,null, result_xml.auth.token, u, result_xml.auth.perms));
		}

		// ---------------------------------------------------------------------------------
		/**
		 * Tokenを確認する
		 **/
		public function checkToken(api_key:String, shared_secret:String, auth_token:String):void{
			var p:Object = new Object();
			p.api_key = api_key;
			p.auth_token = auth_token;
			
			var RM:RestManager = new RestManager();
			RM.doMethod(RestService.METHOD_AUTH_CHECK_TOKEN, p, this.onCheckToken, this.onFaultCheckToken, false, shared_secret);
			
		}
		
		private function onFaultCheckToken(code:Number, massage:String, ro:Object):void{
			// エラー処理
		}
		
		private function onCheckToken(result_xml:XML, ro:Object, t:RTMTransaction):void{
			var u:RTMUser = new RTMUser();
			u.id = result_xml.auth.user.@id;
			u.user_name = result_xml.auth.user.@username;
			u.full_name = result_xml.auth.user.@fullname;
			
			this.dispatchEvent(new AuthEvent(AuthEvent.CHECK_TOKEN, null, null, result_xml.auth.token, u, result_xml.auth.perms));
		}

		// ---------------------------------------------------------------------------------
		/**
		 * Web認証URLを返す
		 * 	HTTP上でFrob⇔Tokenの交換を許可してもらわなくてはいけない。そのURL
		 * 	Frobを取得した時点で（それはTokenを取得するためだし、前回のAuthenticateも無効になっている様子だから）
		 * 	次のステップ[authenticate]に必要
		 **/
		public function getWebAuthURL(api_key:String, shared_secret:String, frob:String):String{
			var ret:String = "http://www.rememberthemilk.com/services/auth/";
			var p:RestParameters= new RestParameters();
			p.addParam("api_key", api_key);
			p.addParam("perms", "delete");
			p.addParam("frob", frob);
			var param:String = p.getParameterStringWithSig(shared_secret);
			return ret + "?" + param;
		}

	}
}